/*
 * Created on 2005-3-12
 */
package com.hd123.rumba.user;

import java.util.Date;
import java.util.List;

import net.sf.hibernate.FlushMode;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Query;
import net.sf.hibernate.type.Type;

import com.hd123.rumba.domain.IDomain;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.exception.DuplicateIdException;
import com.hd123.rumba.exception.ParameterException;
import com.hd123.rumba.runtime.Manager;
import com.hd123.rumba.sql.ResultPage;
import com.hd123.rumba.sql.SQLSubquery;

/**
 * @author caili
 */
public class DepartmentMgr extends Manager implements IDepartmentMgr {

  public static IDepartmentMgr instance;

  public static IDepartmentMgr getInstance() {
    if (instance == null)
      instance = new DepartmentMgr();
    return instance;
  }

  private DepartmentMgr() {
    super();
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#createDepartment(com.hd123.rumba.domain.IDomain,
   *      java.lang.String, java.lang.String)
   */
  public Department createDepartment(IDomain domain, String code, String name)
      throws HibernateException, BusinessException {
    this.checkParameterNotNull(code, "code");
    this.checkParameterNotNull(name, "name");
    Department dept = getDepartmentByCode(domain, code);
    if (dept != null) {
      throw new DuplicateIdException("已经存在code为" + code + "的权限");
    }
    dept = new Department();
    dept.setDomain(domain);
    dept.setCode(code);
    dept.setName(name);
    return dept;
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#getDepartment(java.lang.String)
   */
  public Department getDepartment(String uuid) throws HibernateException {
    Department dept = null;
    if (uuid != null)
      dept = (Department) getSession().get(Department.class, uuid);
    return dept;
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#getDepartmentByCode(com.hd123.rumba.domain.IDomain,
   *      java.lang.String)
   */
  public Department getDepartmentByCode(IDomain domain, String code) throws HibernateException,
      BusinessException {
    Department dept = null;
    if (code != null) {
      List list = getSession().find("from IDepartment p where p.domain.uuid=? and p.code=?",
          new Object[] {
              domain.getUuid(), code.toUpperCase() }, new Type[] {
              Hibernate.STRING, Hibernate.STRING });
      if (list.size() > 0) {
        dept = (Department) list.get(0);
      }
    }
    return dept;
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#saveDepartment(com.hd123.rumba.user.Department)
   */
  public void saveDepartment(IDepartment dept) throws HibernateException, BusinessException {
    this.checkParameterNotNull(dept, "dept");
    if (dept.getUuid() != null) {
      getSession().setFlushMode(FlushMode.COMMIT);
      Department edept = getDepartmentByCode(dept.getDomain(), dept.getCode());
      if (edept != null && !edept.equals(dept)) {
        throw new DuplicateIdException("已经存在code为" + dept.getCode() + "的部门");
      }
    }
    dept.setLastModified(new Date());
    getSession().saveOrUpdate(dept);
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#removeDepartment(com.hd123.rumba.user.Department)
   */
  public void removeDepartment(IDepartment dept) throws HibernateException, BusinessException {
    this.checkParameterNotNull(dept, "dept");
    List list = createUsersList(dept);
    for (int i = 0; i < list.size(); ++i) {
      User user = (User) list.get(i);
      user.setDepartment(null);
      getSession().update(user);
    }
    getSession().delete(dept);
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#createAllDepartmentsList(com.hd123.rumba.domain.IDomain)
   */
  public List createAllDepartmentsList(IDomain domain) throws HibernateException, BusinessException {
    if (domain == null) {
      throw new ParameterException("必须的参数domain不能为null");
    }
    Query q = getSession().createQuery("from Department d where d.domain.uuid=? order by d.code");
    q.setString(0, domain.getUuid());
    return q.list();
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#createAllDepartmentsPage(com.hd123.rumba.domain.IDomain,
   *      int, int)
   */
  public ResultPage createAllDepartmentsPage(IDomain domain, int pageSize, int page)
      throws Exception, ParameterException {
    if (domain == null) {
      throw new ParameterException("必须的参数domain不能为null");
    }
    SQLSubquery sq = new SQLSubquery();
    sq.addSelect("d");
    sq.addFrom("Department", "d");
    sq.addWhere("d.domain.uuid=?", domain.getUuid());
    sq.addOrder("d.code", "asc");
    return ResultPage.createHibernateResultPage(getSession(), sq, pageSize, page);
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#createUsersList(com.hd123.rumba.user.Department)
   */
  public List createUsersList(IDepartment dept) throws HibernateException, BusinessException {
    return getSession().find("from IUser u where u.department.uuid = ? order by u.login",
        dept.getUuid(), Hibernate.STRING);
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#assignUserToDepartment(com.hd123.rumba.user.User,
   *      com.hd123.rumba.user.IDepartment)
   */
  public void assignUserToDepartment(IUser user, IDepartment dept) throws HibernateException,
      BusinessException {
    this.checkParameterNotNull(user, "user");
    this.checkParameterNotNull(dept, "dept");
    user.setDepartment(dept);
    getSession().saveOrUpdate(user);
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.hd123.rumba.user.IDepartmentMgr#removeUserFromDepartment(com.hd123.rumba.user.User,
   *      com.hd123.rumba.user.IDepartment)
   */
  public void removeUserFromDepartment(IUser user, IDepartment dept) throws HibernateException,
      BusinessException {
    this.checkParameterNotNull(user, "user");
    this.checkParameterNotNull(dept, "dept");
    user.setDepartment(null);
    getSession().saveOrUpdate(user);
  }
}
